﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Data;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;
using HTMapLib;
using MapControl;
using MapControl.Misc;
using MapControl.Misc.DAL;
using MapControl.Misc.GPSPoint;
using MapXLib;

namespace GPSMap
{
    

    public partial class ucReviewGPSData_Testing : UserControl
    {
        public ucVectShapeMap _objMapControl;
        //private BindingSource bsGPSData;
        //private ucGPSDataGridView _objUcGPSGridView;
        //private frmGPSTracking _frmParent;
        //private AirPortRepository _airPortRespository;
        public DataTable _dtRoute;
        public int _routeIndex;

        public ucReviewGPSData_Testing(frmGPSTracking_Testing objFrmGPSTracking, ComPort comPort)
        {
            InitializeComponent();
            //_airPortRespository = new AirPortRepository(GeneralClass.appDBFile);
            //_frmParent = objFrmGPSTracking;
            _objMapControl = objFrmGPSTracking.mapControl;
            _objMapControl.ucMap1.AxMap_ClickEvent += new System.EventHandler(this.axMap1_ClickEvent);
            _objMapControl.ucMap1.AxMap_MouseMoveEvent += new AxMapXLib.CMapXEvents_MouseMoveEventHandler(AxMap_MouseMoveEvent);
        }

        private string REPLAY_POSITION_LAYER = "REPLAY_POSITION_LAYER";
        private string REPLAY_POLYLINE_LAYER = "REPLAY_POLYLINE_LAYER";

        private string POSITION_LAYER = "POSITION_LAYER";
        private string POLYLINE_LAYER = "POLYLINE_LAYER";

        private void ucGPSData_Load(object sender, EventArgs e)
        {
            InitGPSGridViewControl();

            InitTrackBar();
            //tabControlFunction.Size = new Size(503, 200);
            splitContainer2.SplitterDistance = splitContainer2.Height - 160;

            btnPause.Visible = false;

            //Thêm lớp view layer theo CSDL hiện tại
            _objMapControl.ucMap1.miAddLayer(POSITION_LAYER, LAYERTYPE.POINT);
            _objMapControl.ucMap1.miAddLayer(POLYLINE_LAYER, LAYERTYPE.POLYLINE);

            //Thêm lớp view replay
           _objMapControl.ucMap1.miAddLayer(REPLAY_POSITION_LAYER, LAYERTYPE.POINT);
           _objMapControl.ucMap1.miAddLayer(REPLAY_POLYLINE_LAYER, LAYERTYPE.POLYLINE);
        }


        #region "GPSGridView Controls"
        private void InitGPSGridViewControl()
        {
            //_objUcGPSGridView = new ucGPSDataGridView(_objMapControl);
            _objUcGPSGridView.InitControl(_objMapControl, true);
            //_objUcGPSGridView.DataGridViewGPSData_MouseDoubleClickEvent += new System.Windows.Forms.MouseEventHandler(this.dataGridViewGPSData_MouseDoubleClick);
            //_objUcGPSGridView.DataGridViewGPSData_CurrentCellChangedEvent += new EventHandler(this.dataGridViewGPSData_CurrentCellChanged);
            _objUcGPSGridView.Dock = DockStyle.Fill;
            splitContainer2.Panel1.Controls.Add(_objUcGPSGridView);
        }
        //private void dataGridViewGPSData_MouseDoubleClick(object sender, MouseEventArgs e)
        //{
        //    if (_objUcGPSGridView.DataGridViewGPS.CurrentRow != null)
        //    {
        //        BaseGPSPoint objPoint = new GPSNormalPoint(GeneralClass.dbTestGPS.Rows[_objUcGPSGridView.DataGridViewGPS.CurrentCell.RowIndex]);
        //        _objMapControl.ucMap1.Map.ZoomTo(_objMapControl.ucMap1.Map.Zoom, objPoint.objGPSData.LonGPS, objPoint.objGPSData.LatGPS);
        //        _objMapControl.Refresh();

        //        Graphics g = _objMapControl.ucMap1.Map.CreateGraphics();
        //        objPoint.Draw(g, Color.Red);
        //    }
        //}

        //private void dataGridViewGPSData_CurrentCellChanged(object sender, EventArgs e)
        //{
        //    if (_objUcGPSGridView.DataGridViewGPS.CurrentRow != null)
        //    {
        //        int airport_id = int.Parse(GeneralClass.dbTestGPS.Rows[_objUcGPSGridView.DataGridViewGPS.CurrentCell.RowIndex]["airport_id"].ToString());
        //        Airport objAirport = _airPortRespository.GetAirportById(airport_id);

        //        BaseGPSPoint objPoint = new GPSNormalPoint(GeneralClass.dbTestGPS.Rows[_objUcGPSGridView.DataGridViewGPS.CurrentCell.RowIndex]);
        //        toolStripStatusLabel1.Text = string.Format("Cách sân bay \"{0}\" khoảng {1} km", objAirport.Airport_Name, objPoint.objGPSData.Distance.ToString("#,###"));
        //    }
        //}
        #endregion

        private void ucGPSData_Resize(object sender, EventArgs e)
        {
            trackBarLeft.Size = new Size(panelTrackBarLeft.Size.Width/2, trackBarLeft.Size.Height);
        }

        private void InitTrackBar()
        {
            trackBarLeft.Minimum = trackBarRight.Minimum = 0;
            trackBarLeft.Maximum = trackBarRight.Maximum = _objUcGPSGridView.DataGridViewGPS.Rows.Count;
            trackBarLeft.Value = 0;
            trackBarRight.Value = trackBarRight.Maximum;
            //lblValueLeft.Text = trackBarLeft.Value.ToString("#,##0");
            numericUpDownLeft.Value = trackBarLeft.Value;
            //lblValueRight.Text = trackBarRight.Value.ToString("#,##0");
            numericUpDownRight.Value = trackBarRight.Value;
            

        }
        /// <summary>
        /// Thay đổi giá trị min max của trackbar
        /// </summary>
        private void TrackBarValueChanged()
        {
            //lblValueLeft.Text = trackBarLeft.Value.ToString("#,##0");
            //lblValueRight.Text = trackBarRight.Value.ToString("#,##0");

            _objUcGPSGridView.LoadDataGridView(trackBarLeft.Value, trackBarRight.Value);
            if (GeneralClass.dbTestGPS.Rows.Count > 0)
                GeneralClass.currGPSData = new GPSCurrentPoint(GeneralClass.dbTestGPS.Rows[GeneralClass.dbTestGPS.Rows.Count - 1]);
            _objMapControl.Refresh();
        }

        private void trackBarRight_ValueChanged(object sender, EventArgs e)
        {
            if (trackBarRight.Value < trackBarLeft.Value)
            {
                trackBarRight.Value = trackBarLeft.Value;
            }
            //numericUpDownRight.Text = trackBarRight.Value.ToString();
            numericUpDownRight.Value = trackBarRight.Value;
            TrackBarValueChanged();    
            
        }

        private void trackBarLeft_ValueChanged(object sender, EventArgs e)
        {
            if (trackBarLeft.Value > trackBarRight.Value)
            {
                trackBarLeft.Value = trackBarRight.Value;
            }
            numericUpDownLeft.Value = trackBarLeft.Value;
            TrackBarValueChanged();
        }

        #region Test truyền dữ liệu qua cổng COM

        private int indexRow = 0;
        private Timer TestSendDataTimer = new Timer();
        public void TestSendDataTimer_Tick(object source, EventArgs e)
        {
            if (TestSendDataTimer.Enabled)
            {
                BaseGPSPoint gpsdata = new GPSNormalPoint(GeneralClass.dbTestGPS.Rows[indexRow]);
                _objUcGPSGridView.DataGridViewGPS.CurrentCell =
                    _objUcGPSGridView.DataGridViewGPS.Rows[indexRow].Cells["showname"];
                _objUcGPSGridView.DataGridViewGPS.Rows[indexRow].Selected = true;
                char[] pack = gpsdata.objGPSData.ConverToByteArray();
                GeneralClass.objPort.SendGPSData(pack);
                indexRow++;

                if (indexRow == GeneralClass.dbTestGPS.Rows.Count)
                {
                    indexRow = 0;
                    if (!chkIsRepeat.Checked)
                    {
                        TestSendDataTimer.Stop();
                        TestSendDataTimer.Enabled = false;
                        btnSendToComPort.Text = "Gửi toàn bộ";
                    }

                }
            }

        }

        private void btnSendToComPort_Click(object sender, EventArgs e)
        {
            if (!TestSendDataTimer.Enabled)
            {
                if (_objUcGPSGridView.DataGridViewGPS.Rows.Count == 0)
                {
                    MessageBox.Show("Không có dữ liệu test để truyền!");
                    return;
                }

                if (!GeneralClass.objPort.IsOpen())
                {
                    MessageBox.Show("Chưa mở cổng COM");
                    return;
                }

                btnSendToComPort.Text = "Dừng Test data";
                TestSendDataTimer.Interval = (int)(numericUpDownSpeed.Value*1000);
                TestSendDataTimer.Enabled = true;
                TestSendDataTimer.Tick += new System.EventHandler(TestSendDataTimer_Tick);
                TestSendDataTimer.Start();
            }
            else
            {
                TestSendDataTimer.Stop();
                TestSendDataTimer.Enabled = false;
                btnSendToComPort.Text = "Gửi toàn bộ";
            }
        }
        #endregion

        private void btnReset_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Bạn có chắc xóa hết dữ liệu GPS?", "Thông báo", 
                MessageBoxButtons.YesNo, 
                MessageBoxIcon.Information, 
                MessageBoxDefaultButton.Button1) == DialogResult.Yes)
            {
                GPSDataRepository.DeleteAll();
                _objUcGPSGridView.LoadDataGridView(0, 0);
                _objMapControl.Refresh();
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            //if(GeneralClass.objPort.IsOpen())
            //{
            //    MessageBox.Show("Cổng COM đang mở. Chỉ chọn xem lại file CSDL khác khi đã đóng cổng COM.");
            //    return;
            //}

            OpenFileDialog obj = new OpenFileDialog();
            obj.Multiselect = false;
            obj.ShowDialog();
            if (obj.FileName != "")
            {
                GeneralClass.gpsDBFile = Path.GetFileName(obj.FileName);
                txtFilePath.Text = obj.FileName;
                GPSDataRepository.ConnectionString = string.Format("DataSource={0}; Password=''", obj.FileName);
                GeneralClass.UpgradeGPSData();
                _objUcGPSGridView.LoadDataGridView(0, 0);
                LoadDatabaseIntoLayer();
                InitTrackBar();
            }


        }

        /// <summary>
        /// Cho biết trạng thái chạy replay:
        /// 0: Đang dừng
        /// 1: Đang chạy
        /// 2: Tạm dừng
        /// </summary>
        private int isReplay = 0;

        private int indexReplay = 0;
        private DataTable dbReplay;
        private void btnReplay_Click(object sender, EventArgs e)
        {
            //delMapxGenFeature(REPLAY_POSITION_LAYER, "meas-1");
            //delMapxGenFeature(REPLAY_POSITION_LAYER, "meas-2");
            //delMapxGenFeature(REPLAY_POSITION_LAYER, "meas_line");
            //measureMode = 1;

            if (isReplay == 0) //Nếu đang dừng thì Start replay
            {
                if (SetDataInitForHistoryRoute())
                {
                    isReplay = 1;
                    btnReplay.Text = "Kết thúc chạy";
                    btnPause.Text = "Tạm dừng";
                    btnPause.Visible = true;
                    //GeneralClass.dbTestGPS.Clear();
                    //dbReplay = GPSDataRepository.LoadDatabase(trackBarLeft.Value, trackBarRight.Value);
                    this.progressBar.Visible = true;
                    HistoryRouteTimer.Start();
                }
            }
            else
            {
                isReplay = 0;
                btnReplay.Text = "Xem lại quá trình bay";
                btnPause.Text = "Tạm dừng";
                btnPause.Visible = false;
                HistoryRouteTimer.Stop();
                //_objUcGPSGridView.LoadDataGridView(trackBarLeft.Value, trackBarRight.Value);
                //if (GeneralClass.dbTestGPS.Rows.Count > 0)
                    //GeneralClass.currGPSData = new GPSCurrentPoint(GeneralClass.dbTestGPS.Rows[GeneralClass.dbTestGPS.Rows.Count - 1]);
            }
           
            return;

            if (isReplay == 0) //Nếu đang dừng thì Start replay
            {
                isReplay = 1;
                btnReplay.Text = "Kết thúc chạy";
                btnPause.Text = "Tạm dừng";
                btnPause.Visible = true;
                GeneralClass.dbTestGPS.Clear();
                dbReplay = GPSDataRepository.LoadDatabase(trackBarLeft.Value, trackBarRight.Value);
                timer1.Interval = 1000;
                timer1.Start();
            }
            else //Nếu không phải đang chạy thì Stop replay
            {
                isReplay = 0;
                btnReplay.Text = "Xem lại quá trình bay";
                btnPause.Text = "Tạm dừng";
                btnPause.Visible = false;
                indexReplay = 0;
                timer1.Stop();
                _objUcGPSGridView.LoadDataGridView(trackBarLeft.Value, trackBarRight.Value);
                if (GeneralClass.dbTestGPS.Rows.Count > 0)
                    GeneralClass.currGPSData = new GPSCurrentPoint(GeneralClass.dbTestGPS.Rows[GeneralClass.dbTestGPS.Rows.Count - 1]);
                _objMapControl.Refresh();
                
            }
        }

        private void trackBarLeft_Scroll(object sender, EventArgs e)
        {

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (indexReplay < dbReplay.Rows.Count)
            {
                //Copy datarow
                GeneralClass.dbTestGPS.ImportRow(dbReplay.Rows[indexReplay++]);
                _objUcGPSGridView.DataGridViewGPS.CurrentCell = _objUcGPSGridView.DataGridViewGPS.Rows[_objUcGPSGridView.DataGridViewGPS.Rows.Count - 1].Cells["showname"];
                _objUcGPSGridView.DataGridViewGPS.CurrentCell.Selected = true;
                GeneralClass.currGPSData = new GPSCurrentPoint(GeneralClass.dbTestGPS.Rows[GeneralClass.dbTestGPS.Rows.Count - 1]);
                _objMapControl.Refresh();
            }
            else //Nếu replay xong
            {
                btnReplay.PerformClick();
            }
        }

        private void numericUpDownLeft_ValueChanged(object sender, EventArgs e)
        {
            if (numericUpDownLeft.Value > numericUpDownRight.Value)
            {
                numericUpDownLeft.Value = numericUpDownRight.Value;
                trackBarLeft.Value = (int)numericUpDownLeft.Value;
            }
            else
            {
                trackBarLeft.Value = (int)numericUpDownLeft.Value;
            }
        }

        private void numericUpDownRight_ValueChanged(object sender, EventArgs e)
        {
            if (numericUpDownRight.Value < numericUpDownLeft.Value)
            {
                numericUpDownRight.Value = numericUpDownLeft.Value;
                trackBarRight.Value = (int)numericUpDownRight.Value;
            }
            else
            {
                trackBarRight.Value = (int)numericUpDownRight.Value;
            }
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            if (isReplay == 1) //Nếu đang chạy thì nhấn tạm dừng
            {
                isReplay = 2;
                btnPause.Text = "Chạy tiếp";
                HistoryRouteTimer.Stop();
            }
            else if (isReplay == 2) //Nếu đang tạm dừng thì nhấn chạy tiếp
            {
                isReplay = 1;
                btnPause.Text = "Tạm dừng";
                HistoryRouteTimer.Start();
            }

            //if (isReplay == 1) //Nếu đang chạy thì nhấn tạm dừng
            //{
            //    isReplay = 2;
            //    btnPause.Text = "Chạy tiếp";
            //    timer1.Stop();
            //}
            //else if (isReplay == 2) //Nếu đang tạm dừng thì nhấn chạy tiếp
            //{
            //    isReplay = 1;
            //    btnPause.Text = "Tạm dừng";
            //    timer1.Start();
            //}
        }

        #region "Test Layers"

        public void AxMap_MouseMoveEvent(object sender, AxMapXLib.CMapXEvents_MouseMoveEvent e)
        {
            //Lấy 
            m_x = e.x;
            m_y = e.y;
        }

        public float m_x, m_y;
        public double measureMode = 0;
        public double measure_P1_x;
        public double measure_P1_y;
        private void axMap1_ClickEvent(object sender, EventArgs e)
        {
            double mapX = 0;
            double mapY = 0;
            _objMapControl.ucMap1.Map.ConvertCoord(ref m_x, ref m_y, ref mapX, ref mapY, MapXLib.ConversionConstants.miScreenToMap);

            if (measureMode == 1)
            {
                _objMapControl.ucMap1.miAddGeneralPoint(REPLAY_POSITION_LAYER, mapX, mapY, "meas-1");
                measureMode = 2;
                measure_P1_x = mapX;
                measure_P1_y = mapY;
            }
            else if (measureMode == 2)
            {
                _objMapControl.ucMap1.miAddGeneralPoint(REPLAY_POSITION_LAYER, mapX, mapY, "meas-2");
                double ran = Math.Pow(mapX - measure_P1_x, 2) + Math.Pow(mapY - measure_P1_y, 2);
                ran = Math.Sqrt(ran);

                _objMapControl.ucMap1.addMapxGenLine(REPLAY_POSITION_LAYER, "meas_line", measure_P1_x, measure_P1_y, mapX, mapY);
                double deX, deY;
                deX = mapX - measure_P1_x;
                deY = mapY - measure_P1_y;

                String outstr = String.Format("x = {0:F2} y = {1:F2} ran = {2:F2}", deY, deX, ran);
                MessageBox.Show(outstr);

                measureMode = 0;
            }

        }
        #endregion


        private void LoadDatabaseIntoLayer()
        {
            this._dtRoute = GeneralClass.dbTestGPS;
            if (this._dtRoute == null)
            {
                return;
            }
            else
            {
                
                this.lbl1.Visible = true;
                this.progressBar.Visible = true;
                this.progressBar.Maximum = this._dtRoute.Rows.Count;
                this.progressBar.Minimum = 0;
                this.progressBar.Value = 0;

                for (int i = 1; i < this._dtRoute.Rows.Count; i++)
                {
                    DataRow dr = this._dtRoute.Rows[i];
                    this.lbl1.Text = string.Format("{0:F0}%", i * 100 / this._dtRoute.Rows.Count);
                    this.progressBar.Value = this.progressBar.Value + 1;
                    double lon0 = Convert.ToDouble(this._dtRoute.Rows[i - 1]["lon"]);
                    double lat0 = Convert.ToDouble(this._dtRoute.Rows[i - 1]["lat"]);

                    double lon1 = Convert.ToDouble(this._dtRoute.Rows[i]["lon"]);
                    double lat1 = Convert.ToDouble(this._dtRoute.Rows[i]["lat"]);

                    //Vẽ line nối 2 GPS
                    this._objMapControl.ucMap1.miAddStyleLine(POLYLINE_LAYER, STYLE_Line_TYPE.HISTORYLINE, lon0, lat0, lon1, lat1, "L" + i.ToString());

                    //Vẽ điểm GPS
                    this._objMapControl.ucMap1.miAddStylePoint(POSITION_LAYER, lon1, lat1, "P" + i.ToString(), STYLESINGLETYPE.NORMALPOINT_RED);
                }
                this.lbl1.Visible = false;
                this.progressBar.Visible = false;
            }
        }

        /// <summary>
        /// Hàm khởi tạo xem lại History
        /// </summary>
        /// <returns></returns>
        public bool SetDataInitForHistoryRoute()
        {
            this._dtRoute = GeneralClass.dbTestGPS;
            if (this._dtRoute == null)
            {
                return false;
            }
            else
            {
                this.progressBar.Visible = true;
                this.progressBar.Maximum = this._dtRoute.Rows.Count;
                this.progressBar.Minimum = 0;

                double lon = Convert.ToDouble(this._dtRoute.Rows[0]["lon"]);
                double lat = Convert.ToDouble(this._dtRoute.Rows[0]["lat"]);

                this._objMapControl.ucMap1.miAddStylePoint(REPLAY_POSITION_LAYER, lon, lat, "0", STYLESINGLETYPE.NORMALPOINT_RED);
                this._objMapControl.ucMap1.miToolZoomToPoint(lon, lat);


                if (this._dtRoute.Rows.Count == 1)
                    return false;
                else
                {
                    this._routeIndex = 1;
                    return true;
                }
            }
        }

       

        private void HistoryRouteTimer_Tick(object sender, EventArgs e)
        {
            //Copy datarow
            _objUcGPSGridView.DataGridViewGPS.CurrentCell = _objUcGPSGridView.DataGridViewGPS.Rows[this._routeIndex - 1].Cells["showname"];
            _objUcGPSGridView.DataGridViewGPS.CurrentCell.Selected = true;
            GeneralClass.currGPSData = new GPSCurrentPoint(GeneralClass.dbTestGPS.Rows[this._routeIndex - 1]);

            double lon0 = Convert.ToDouble(this._dtRoute.Rows[this._routeIndex - 1]["lon"]);
            double lat0 = Convert.ToDouble(this._dtRoute.Rows[this._routeIndex - 1]["lat"]);

            double lon1 = Convert.ToDouble(this._dtRoute.Rows[this._routeIndex]["lon"]);
            double lat1 = Convert.ToDouble(this._dtRoute.Rows[this._routeIndex]["lat"]);

            this.lbl1.Text = string.Format("{0:F0}%", this._routeIndex * 100 / this._dtRoute.Rows.Count);
            if (this.progressBar.Value + 1 < this.progressBar.Maximum)
                this.progressBar.Value = this.progressBar.Value + 1;


            //Xóa điểm GPS old
            //this.miDeleteFeature(REPLAY_POLYLINE_LAYER, "P" + (this._routeIndex - 1).ToString());

            //Vẽ line nối 2 GPS
            _objMapControl.ucMap1.miAddStyleLine(REPLAY_POLYLINE_LAYER, STYLE_Line_TYPE.HISTORYLINE, lon0, lat0, lon1, lat1, "L" + this._routeIndex.ToString());

            //Vẽ lại GPS old
            //this.miAddStylePoint(REPLAY_POLYLINE_LAYER, lon0, lat0, "P" + (this._routeIndex - 1).ToString(), STYLESINGLETYPE.NORMALPOINT_RED);

            //Vẽ điểm GPS
            this._objMapControl.ucMap1.miAddStylePoint(REPLAY_POSITION_LAYER, lon1, lat1, "P" + this._routeIndex.ToString(), STYLESINGLETYPE.NORMALPOINT_RED);

            this._objMapControl.ucMap1.miToolZoomToPoint(lon1, lat1);

            this._routeIndex += 1;
            if (this._routeIndex >= this._dtRoute.Rows.Count)
            {
                this.HistoryRouteTimer.Enabled = false;
                this._routeIndex = 0;
                MessageBox.Show("Finish!");
            }
        }

        private char[] ReaderGPSToByte(int pos)
        {
            BaseGPSPoint gpsdata = new GPSNormalPoint(GeneralClass.dbTestGPS.Rows[pos]);
            char[] data = gpsdata.objGPSData.ConverToByteArray();
            char[] buff = new char[GeneralClass.FULL_DATA_LEN];
            buff = GeneralClass.objPort.CreateDataPack(buff, data);
            return buff;
        }

        private int caseIndex = 0;
        private int pos = 0;
        private char[] remainBuff;
        private void btnTestSendToComPort_Click(object sender, EventArgs e)
        {
            char[] sendBuff = null;
            int indexBuff = 0; //vị trí buffer
            Random r = new Random();
            
            switch (caseIndex)
            {
                case 0: //Gửi dữ liệu bao gồm: 1 gps full và 1 gps thiếu
                    //Lấy kích thước ngẫu nhiên của đoạn dữ liệu cần gửi
                    int len = r.Next(0, GeneralClass.FULL_DATA_LEN);
                    sendBuff = new char[GeneralClass.FULL_DATA_LEN + len];

                    //Đọc dữ liệu 1
                    char[] buff1 = ReaderGPSToByte(pos++);

                    //Đọc dữ liệu 2: 
                    char[] buff2 = ReaderGPSToByte(pos++);

                    //Copy toàn bộ dữ liệu buff1 vào sendBuff
                    Array.Copy(buff1, sendBuff, buff1.Length);
                    indexBuff = buff1.Length;

                    //Copy một phần dữ liệu 2
                    if (len > 0)
                    {
                        //Copy một đoạn len của dữ liệu buff2 vào sendBuff tại vị trí indexBuff
                        Array.Copy(buff2, 0, sendBuff, indexBuff, len);
                        //Chuyển phần dữ liệu còn lại của buff2 sang remainBuff
                        remainBuff = new char[buff2.Length - len];
                        Array.Copy(buff2, len, remainBuff, 0, buff2.Length - len);
                    }
                    
                    //Bước sau sang trường hợp 1
                    caseIndex++;
                    break;
                case 1: //gửi dữ liệu còn lại, gồm: 1 gsp thiếu phần còn lại và 1 gps full
                    sendBuff = new char[remainBuff.Length + GeneralClass.FULL_DATA_LEN];
                    //Đọc dữ liệu 3
                    char[] buff3 = ReaderGPSToByte(pos++);

                    //Copy dữ liệu remainBuff còn lại vào đầu sendBuff
                    Array.Copy(remainBuff, sendBuff, remainBuff.Length);
                    
                    //Copy một dữ liệu buff3 vào sendBuff tại vị trí remainBuff.Length
                    Array.Copy(buff3, 0, sendBuff, remainBuff.Length, buff3.Length);
                    
                    //Bước sau quay về trường hợp 0
                    caseIndex = 0;
                    break;
            }
            
            //===========================================
            //Bắt đầu gửi dữ liệu
            GeneralClass.objPort.SendGPSData(sendBuff);
        }

        private void chkIsRandomError_CheckedChanged(object sender, EventArgs e)
        {
            GeneralClass.objPort.IsRandomError = chkIsRandomError.Checked;
        }

        private void chkIsRepeat_CheckedChanged(object sender, EventArgs e)
        {
            
        }

        private void OpenCOMPort()
        {
            //Mở kết nối
            try
            {
                //Kết nối về CSDL chuẩn
                string msg = GeneralClass.ConnectDatabase(txtFilePath.Text);
                if (msg != "")
                {
                    MessageBox.Show(msg);
                    return;
                }
                btnOpenCOMPort.Text = "Đóng cổng COM";
                GeneralClass.objPort.PortName = Properties.Settings.Default.PortName;
                GeneralClass.objPort.BaudRate = Properties.Settings.Default.BaudRate;
                GeneralClass.objPort.StopBits = Properties.Settings.Default.StopBits;
                GeneralClass.objPort.DataBits = Properties.Settings.Default.DataBits;
                GeneralClass.objPort.Parity = Properties.Settings.Default.Parity;

                GeneralClass.objPort.comPortOpen();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Xảy ra lỗi sau khi kết nối:\n" + ex.Message, "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                CloseCOMPort();
            }
        }

        private void CloseCOMPort()
        {
            //đóng kết nối
            try
            {
                btnOpenCOMPort.Text = "Mở cổng COM";
                GeneralClass.objPort.comPortClose();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Xảy ra lỗi sau khi kết nối:\n" + ex.Message, "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public event EventHandler OpenCOMPort_ClickEvent;
        private void btnOpenCOMPort_Click(object sender, EventArgs e)
        {
            try
            {
                if (!GeneralClass.objPort.IsOpen())
                {
                    OpenCOMPort();
                }
                else
                {
                    CloseCOMPort();
                }

                if (OpenCOMPort_ClickEvent != null)
                    OpenCOMPort_ClickEvent(sender, e);
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("{0} - {1}", ex.Message, ex.StackTrace));
            }
        }
    }
}
